package demo.jvisualvm.classloader;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * 自定义类加载器
 *
 * @author ZH.Team
 * @version 1.0.0
 * @email "mailto:ZH.Team@zhxx.com"
 * @date 2024.09.22 14:47
 * @since 1.0.0
 */
public class CustomizerClassLoader extends ClassLoader {

    /** Class loader name */
    private String classLoaderName;

    /** 文件后缀 */
    private String fileExtension = ".class";

    /** 获取到当前项目的class编译路径 */
    private static final String PATH = CustomizerClassLoader.class.getResource("/").getPath();

    /**
     * Customizer class loader
     *
     * @param classLoaderName class loader name
     * @since 1.0.0
     */
    public CustomizerClassLoader(String classLoaderName) {
        super();
        this.classLoaderName = classLoaderName;
    }

    /**
     * Customizer class loader
     *
     * @param parent          parent
     * @param classLoaderName class loader name
     * @since 1.0.0
     */
    public CustomizerClassLoader(ClassLoader parent, String classLoaderName) {
        super(parent);
        this.classLoaderName = classLoaderName;
    }

    /**
     * 获取到对应的类
     *
     * @param clzName clz name
     * @return the class
     * @throws ClassNotFoundException class not found exception
     * @since 1.0.0
     */
    @Override
    protected Class<?> findClass(String clzName) throws ClassNotFoundException {
        byte[] bytes = this.loadClassData(clzName);
        return super.defineClass(clzName, bytes, 0, bytes.length);
    }

    /**
     * 根据名称去获取到类的二进制数据
     *
     * @param clzName clz name
     * @return the byte [ ]
     * @since 1.0.0
     */
    private byte[] loadClassData(String clzName) {
        // 将名称替换成对应的路径
        clzName = clzName.replace(".", File.separator);
        byte[] bytes;
        try {
            bytes = Files.readAllBytes(Paths.get(PATH + "/" + clzName + this.fileExtension));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return bytes;
    }

}
